// $codepro.audit.disable
/**
 * package for all of the controller classes to fit MVC design pattern
 */
package javamonsters.controller;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Map.Entry;

import javamonsters.model.Player;
import javamonsters.model.Ship;
import javamonsters.model.ShipItem;
import javamonsters.model.ShipYard;
import javamonsters.universe.application.UniverseController;
import javamonsters.view.ShipYardView;
import javamonsters.view.SpaceTraders;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;



/**
 * This is the controller for the Ship Yard model
 * 
 * @author Evan LaHurd
 *
 * @version 1.0
 */
public class ShipYardController {
	
	/**
	 * a multiplier for the fuel cost
	 */
	private final int fuelMultiplier;
	
	/**
	 * a space trader object
	 */
	private final SpaceTraders spaceTraders;
	
	/**
	 * view of the shipyard
	 */
	private final ShipYardView view;
	
	/**
	 * shipyard object
	 */
	private ShipYard shipYard;
	
	/**
	 * default renderer object
	 */
	private DefaultListCellRenderer renderer;
	
	/**
	 * Constructor for ShipYardController.
	 * @param view ShipYardView
	 * @param spaceTraders SpaceTraders
	 */
	public ShipYardController(ShipYardView view, SpaceTraders spaceTraders) {
		this.view = view;
		this.spaceTraders = spaceTraders;
		fuelMultiplier = 10;
		view.getBuyShipButton().addActionListener(new BuyShipButtonListener());
		view.getToMarketButton().addActionListener(new ToMarketButtonListener());
		view.getSaveButton().addActionListener(new SaveButtonListener());
		view.getBackToMapButton().addActionListener(new BackToMapButtonListener());
		view.getBuyFuelButton().addActionListener(new BuyFuelButtonListener());
		view.getFuelSlider().addChangeListener(new FuelSliderListener());
	}
	
	/**
	 * Method toString.
	 * @return String
	 */
	public String toString() {
		return super.toString();
	}
	
	/**
	 * The listener for the fuel slider
	 * 
	 * @author evan
	 * @version 1.0
	 */
	private class FuelSliderListener implements ChangeListener  {
		
		/**
		 * Represents a slide of the fuel slider
		 * 
		 * @param e ChangeEvent represents 1 silde of the fuel slider
		 * @throws NumberFormatException
		 * 
		 */
		public void stateChanged(ChangeEvent e) throws NumberFormatException {
			final JSlider source = (JSlider) e.getSource();
			final Integer playerCredits = spaceTraders.getPlayer()
										  .getCredits().intValue();
			view.getFuelToBuyLabel().setText("" + source.getValue());
			view.getFuelCostLabel().setText("" + (source.getValue() * fuelMultiplier));
			//disable button if player doesn't have enough credits to buy the selected fuel amount, enable otherwise
			if (playerCredits != null && playerCredits.compareTo(
					((Integer) Integer.parseInt(
					view.getFuelCostLabel().getText()))) < 0) {
				view.getBuyFuelButton().setEnabled(false);
			} else {
				view.getBuyFuelButton().setEnabled(true);
			}
		}
		
		/**
		 * @return String representation of fuel slider listener 
		 */
		public String toString() {
			return "fuel slider listener";
		}
	}
	
	/**
	 * Buys the selected amount of fuel for the player
	 * 
	 * @author Evan LaHurd
	 *
	 */
	private class BuyFuelButtonListener implements ActionListener {
		
		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
		 * @throws NumberFormatException
		 */
		public void actionPerformed(ActionEvent e) throws NumberFormatException {
			//get the amount of fuel to buy
			final String fuel = view.getFuelToBuyLabel().getText();
			final Integer fuelInt = Integer.parseInt(fuel);
			
			//set fuel to previous fuel plus the amount of fuel they want to buy
			final Ship ship = spaceTraders.getPlayer().getShip();
			final int playerFuel = spaceTraders.getPlayer().getShip().getFuel();
			spaceTraders.getPlayer().getShip().setFuel(playerFuel + fuelInt);
			
			//set the current fuel labels in the ship yard view and the universe side panel view
			view.getCurrentFuelLabel().setText("Current Fuel: " + (playerFuel + fuelInt));
			
			final UniverseController universeController = 
				  spaceTraders.getUniverseController();
			
			universeController.getSideView().getCurrentFuelLabel()
			.setText("" + (playerFuel + fuelInt));
			
			final Integer fuelCost = Integer.parseInt(view.getFuelCostLabel().getText());
			final Player player = spaceTraders.getPlayer();
			final BigDecimal prevCredits = player.getCredits();
			
			//subtract the fuel cost from player's credits
			player.setCredits(prevCredits.subtract(new BigDecimal(fuelCost)));
			
			//set credit labels in ship yard and marketplace
			final MarketplaceController marketplaceController = 
				  spaceTraders.getMarketplaceController();
			
			marketplaceController.getMarketView()
			.getCreditsLabel().setText("" + player.getCredits());
			
			view.getCreditsLabel().setText("" + player.getCredits());
			
			//change slider max value 
			view.getFuelSlider().setMaximum((ship.getMaxFuel() - (playerFuel + fuelInt)));
			
		}
		
		/**
		 * Method toString.
		 * @return String
		 */
		public String toString() {
			return super.toString();
		}
	}
	
	/**
	 * Purchases the selected ship 
	 * 
	 * @author Evan LaHurd
	 *
	 */
	private class BuyShipButtonListener implements ActionListener {
		
		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
		 */
		public void actionPerformed(ActionEvent e) {
			@SuppressWarnings("unchecked")
			final Map.Entry<Ship, ShipItem> selectedValue = 
			(Map.Entry<Ship, ShipItem>) view.getShipList().getSelectedValue();
			
			final Ship playerShip = spaceTraders.getPlayer().getShip();
			 if (playerShip.isSameShip(selectedValue.getKey())) {
				 JOptionPane.showMessageDialog(null, "You already have that ship!");
			 } else if (!selectedValue.getValue().isGray()) {
				shipYard.buyShip(selectedValue.getKey());
				
				//clear the sell list and the map that populates it
				final MarketplaceController marketplaceController = 
						  spaceTraders.getMarketplaceController();
				
				final UniverseController universeController = 
						spaceTraders.getUniverseController();
				
				marketplaceController.getMarketView().getSellListModel().clear();
				
				marketplaceController.getMarket().getSellMap().clear();
				
				universeController
				.getSideView().getCargoModel().clear();
				
				//update all of the UIs that show the player's cargo
				view.getShipList().updateUI();
				spaceTraders.getMarketplaceController().getMarketView().updateUI();
				spaceTraders.getUniverseController().getSideView().updateUI();
				
				view.getCurrentShipLabel().setText(
				"" + selectedValue.getKey().getShipType());
				
				view.getCreditsLabel().setText(
				"" + spaceTraders.getPlayer().getCredits());
				
				marketplaceController.getMarketView()
				.getCreditsLabel().setText("" + spaceTraders.getPlayer().getCredits());
			}
			
		}
		
		/**
		 * Method toString.
		 * @return String
		 */
		public String toString() {
			return super.toString();
		}
	}
	
	/**
	 * takes the player to the marketplace screen
	 * 
	 * @author Evan LaHurd
	 *
	 */
	private class ToMarketButtonListener implements ActionListener {
		
		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
		 */
		public void actionPerformed(ActionEvent e) {
			
			//view.getShipListModel().clear();
			spaceTraders.show("Marketplace View");
		}
		
		/**
		 * Method toString.
		 * @return String
		 */
		public String toString() {
			return super.toString();
		}
	}

	/**
	 * a button listener for the save button
	 * @author John
	 *
	 */
	private class SaveButtonListener implements ActionListener {
	
		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
		 */
		public void actionPerformed(ActionEvent e) {
			spaceTraders.saveGame();
		}
		
		/**
		 * Method toString.
		 * @return String
		 */
		public String toString() {
			return super.toString();
		}
	}

	/**
	 * takes the player back to the universe map screen
	 * 
	 * @author Evan LaHurd
	 *
	 */
	private class BackToMapButtonListener implements ActionListener {
	
		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
		 */
		public void actionPerformed(ActionEvent e) {
			
			final UniverseController universeController = 
					spaceTraders.getUniverseController();
			
			universeController.getSideView()
			.getFuelCostLabel().setText("" + 0);
			
			spaceTraders.show("Dual Universe Panel");
		}
		
		/**
		 * Method toString.
		 * @return String
		 */
		public String toString() {
			return super.toString();
		}
	}
	
	/**
	 * sets a ship yard for the controller, sets a list cell renderer,
	 * and adds all of the buyable ships to the list model
	 * 
	 * @param shipYard the ship yard to be set for this controller
	 */
	public void setShipYard(ShipYard shipYard) {
		this.shipYard = shipYard;
		
		final Map<Ship, ShipItem> shipMap = shipYard.getShipMap();
		for(Entry<Ship,ShipItem> entry : shipMap.entrySet()) {
			view.getShipListModel().addElement(entry);
			renderer = new DefaultListCellRenderer() {

				@SuppressWarnings("unchecked")
				public Component getListCellRendererComponent(
						         JList list, Object value, int index,
				                 boolean isSelected, boolean cellHasFocus) {
				        Component comp = super.getListCellRendererComponent(
				        		 list, value, index, isSelected, cellHasFocus);
				        
				        if(spaceTraders.getPlayer().getCredits().compareTo(
				         (((Entry<Ship, ShipItem>) value).getValue().getPrice())) < 0) {
				        	comp.setForeground(Color.gray);
				        	((Entry<Ship, ShipItem>) value).getValue().setIsGray(true);
				        } else if(spaceTraders.getPlayer().getCredits().compareTo(

				        	(((Entry<Ship, ShipItem>) value).getValue().getPrice())) > 0){
				        	((Entry<Ship, ShipItem>) value).getValue().setIsGray(false);

				        }
				        
				        return this;
				    }
				};
		}
		
		view.getShipList().setCellRenderer(renderer);
	}
	
	/**
	
	 * @return the ship yard view */
	public ShipYardView getShipYardView() {
		return view;
	}
	
	/**
	
	 * @return the ship yard model */
	public ShipYard getShipYard() {
		return shipYard;
	}
	
	

}
